---
seotitle: Serve static assets
seodesc: Learn how to serve static assets with Encore.ts
title: Static Assets
subtitle: How to serve static assets
lang: ts
---

Encore.ts has built-in support for serving static assets (such as images, HTML and CSS files, and JavaScript files).

This is particularly useful when you want to serve a static website or a single-page application (SPA) that has
been pre-compiled into static files.

<GitHubLink
    href="https://github.com/encoredev/examples/tree/main/ts/static-files"
    desc="Example of how to use api.static in to serve static files."
/>


## API Reference

Serving static files in Encore.ts works similarly to regular API endpoints, but using the `api.static` function instead.

```typescript
import { api } from "encore.dev/api";

export const assets = api.static(
  { expose: true, path: "/frontend/*path", dir: "./assets" },
);
```

This will serve all files in the `./assets` directory under the `/frontend` path prefix.

Encore automatically serves `index.html` files at the root of a directory. In the case above,
that means that requesting the URL `/frontend` will serve the file `./assets/index.html`,
and `/frontend/hello` will serve the file `./assets/hello` or `./assets/hello/index.html` (whichever exists).

### Serving static files at the root

By default, Encore requires that API endpoint paths don't conflict with other API endpoints.
This can cause problems when you want to serve static files at the root of your domain (such as by setting `path: "/*path"`),
since that would conflict with all other paths.

To support this use case, Encore allows defining a route as a "fallback route", that gets called only when no other API endpoint matches.

Fallback routes use the syntax `!path` instead of `*path`.

It looks like this:

```typescript
import { api } from "encore.dev/api";

export const assets = api.static(
  { expose: true, path: "/!path", dir: "./assets" },
);
```

### Configuring the 404 response

When a file matching the request isn't found, Encore automatically serves a 404 Not Found response.

You can customize the response by setting the `notFound` option to specify a file that should be served instead:

```typescript
import { api } from "encore.dev/api";

export const assets = api.static(
  { expose: true, path: "/!path", dir: "./assets", notFound: "./not_found.html" },
);
```

## Performance

When defining static files, the files are served directly from the Encore.ts Rust Runtime.
This means that zero JavaScript code is executed to serve the files, freeing up the Node.js
runtime to focus on executing business logic.

This dramatically speeds up both the static file serving,
as well as improving the latency of your API endpoints.
